package com.ssy.lingxi.member.merchant.serviceimpl.web;

import cn.hutool.core.collection.CollectionUtil;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.basic.PlatformRuleTypeEnum;
import com.ssy.lingxi.common.constant.basic.PurchaseContractPayTypeEnum;
import com.ssy.lingxi.common.constant.member.*;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberManageQueryVO;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.AgentAreaBO;
import com.ssy.lingxi.member.merchant.model.bo.MemberDetailLabelBO;
import com.ssy.lingxi.member.merchant.model.bo.WorkflowTaskListBO;
import com.ssy.lingxi.member.merchant.model.constant.*;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.MemberNameVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.ProvinceCodeVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.UpperRelationIdAndAreaCodeVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.UpperRelationIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.*;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberAppraisalPageQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberCreditComplaintPageQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberRecordInspectPageQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberRecordRectifyVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.*;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.*;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.MemberAbilityMaintenanceMemberQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.MemberValidateVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.ValidateIdPageVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.ValidateIdVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.response.*;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.*;
import com.ssy.lingxi.member.merchant.service.feign.IPayFeignService;
import com.ssy.lingxi.member.merchant.service.web.*;
import com.ssy.lingxi.member.merchant.utils.AgentAreaUtil;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 会员能力 - 会员维护相关接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-05-31
 */
@Service
public class MemberAbilityMaintenanceServiceImpl implements IMemberAbilityMaintenanceService {

    @Resource
    private IBaseMemberCacheService memberCacheService;

    @Resource
    private ChannelTypeRepository channelTypeRepository;

    @Resource
    private IBaseMemberValidateService baseMemberValidateService;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private MemberUserRepository memberUserRepository;

    @Resource
    private BaseMemberRuleRepository baseMemberRuleRepository;

    @Resource
    private IBaseMemberDetailService baseMemberDetailService;

    @Resource
    private IBaseMemberRegisterDetailService baseMemberRegisterDetailService;

    @Resource
    private IBaseMemberQualificationService baseMemberQualificationService;

    @Resource
    private IBaseMemberDepositDetailService baseMemberDepositDetailService;

    @Resource
    private IBaseMemberClassificationService baseMemberClassificationService;

    @Resource
    private IBaseCountryAreaService baseCountryAreaService;

    @Resource
    private IBaseMemberHistoryService baseMemberHistoryService;

    @Resource
    private IMemberInspectService memberInspectService;

    @Resource
    private IMemberAppraisalService memberAppraisalService;

    @Resource
    private IMemberRectifyService memberRectifyService;

    @Resource
    private IMemberComplaintService memberComplaintService;

    @Resource
    private IBaseMemberLevelConfigService baseMemberLevelConfigService;

    @Resource
    private IPayFeignService payFeignService;

    @Resource
    private IBaseSiteService siteService;

    @Resource
    private IPlatformMemberRoleRuleService roleRuleService;

    @Resource
    private CountryCodeRepository countryCodeRepository;

    private final List<MemberOuterStatusEnum> outerStatusEnums = Stream.of(
            MemberOuterStatusEnum.DEPOSITING,
            MemberOuterStatusEnum.DEPOSITORY_PASSED,
            MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED,
            MemberOuterStatusEnum.MODIFYING,
            MemberOuterStatusEnum.MODIFY_PASSED,
            MemberOuterStatusEnum.MODIFY_NOT_PASSED
    ).collect(Collectors.toList());

    /**
     * 获取分页查询会员列表页面中各个查询条件下拉选择框的内容
     *
     * @param headers HttpHeaders信息
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberMaintenanceSearchConditionVO> getPageCondition(HttpHeaders headers) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        //规则：
        MemberMaintenanceSearchConditionVO conditionVO = new MemberMaintenanceSearchConditionVO();
        //内部状态
        List<DropdownItem> itemList = MemberInnerStatusEnum.toDropdownItems();
        itemList.add(0, new DropdownItem(0, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setInnerStatus(itemList);

        //外部状态
        itemList = outerStatusEnums.stream().map(e -> new DropdownItem(e.getCode(), e.getMsg())).collect(Collectors.toList());
        itemList.add(0, new DropdownItem(0, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setOuterStatus(itemList);

        //注册来源
        itemList = MemberRegisterSourceEnum.toAbilityDropdownList();
        itemList.add(0, new DropdownItem(0, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setSources(itemList);

        //会员状态
        itemList = Arrays.stream(MemberStatusEnum.values()).sorted(Comparator.comparingInt(MemberStatusEnum::getCode)).map(e -> new DropdownItem(e.getCode(), e.getMsg())).collect(Collectors.toList());
        itemList.add(0, new DropdownItem(0, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setStatus(itemList);

        //获取是否开启saas多租户部署
        Boolean enableMultiTenancy = siteService.isEnableMultiTenancy(headers).getData();

        List<MemberTypeIdAndNameVO> memberTypeList;
        List<RoleIdAndNameVO> roleList;
        if (enableMultiTenancy) {//有开启
            //会员类型（这里返回的是Id）
            memberTypeList = baseMemberValidateService.getSubMemberTypeList(loginUser.getMemberType(), Optional.ofNullable(roleRuleService.subMemberRoles(loginUser.getMemberId())).map(Wrapper::getData).orElse(new ArrayList<>()));
            //会员角色（按照Id升序排序）
            roleList = baseMemberValidateService.getSubRoleList(loginUser.getMemberType(), Optional.ofNullable(roleRuleService.subMemberRoles(loginUser.getMemberId())).map(Wrapper::getData).orElse(new ArrayList<>()));
        } else {//未开启
            //会员类型（这里返回的是Id）
            memberTypeList = baseMemberValidateService.getSubMemberTypeList(loginUser.getMemberType());
            //会员角色（按照Id升序排序）
            roleList = baseMemberValidateService.getSubRoleList(loginUser.getMemberType());
        }
        memberTypeList.add(0, new MemberTypeIdAndNameVO(0L, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setMemberTypes(memberTypeList);
        roleList.add(0, new RoleIdAndNameVO(0L, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setRoles(roleList);

        //会员等级
        List<LevelAndTagVO> levelList = baseMemberLevelConfigService.listSubMemberLevels(loginUser.getMemberId(), loginUser.getMemberRoleId());
        levelList.add(0, new LevelAndTagVO(0, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setLevels(levelList);

        return Wrapper.success(conditionVO);
    }

    /**
     * 分页、模糊查询会员
     *
     * @param headers HttpHeaders信息
     * @param queryVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberMaintenancePageQueryVO>> pageMembers(HttpHeaders headers, MemberAbilityMaintenanceMemberQueryVO queryVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        Specification<MemberRelationDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            //上级会员id和角色Id
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));

            //注册开始时间
            if(StringUtils.hasLength(queryVO.getStartDate())) {
                LocalDateTime startDate = LocalDateTime.parse(queryVO.getStartDate().concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), startDate));
            }

            //注册结束时间
            if(StringUtils.hasLength(queryVO.getEndDate())) {
                LocalDateTime endDate = LocalDateTime.parse(queryVO.getEndDate().concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), endDate));
            }

            //内部状态
            if(NumberUtil.isNullOrZero(queryVO.getInnerStatus())) {
                list.add(criteriaBuilder.notEqual(root.get("innerStatus").as(Integer.class), MemberInnerStatusEnum.NEW.getCode()));
            } else {
                list.add(criteriaBuilder.equal(root.get("innerStatus").as(Integer.class), queryVO.getInnerStatus()));
            }

            //外部状态
            if(NumberUtil.isNullOrZero(queryVO.getOuterStatus())) {
                list.add(root.get("outerStatus").as(Integer.class).in(outerStatusEnums.stream().map(MemberOuterStatusEnum::getCode).collect(Collectors.toList())));
            } else {
                list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), queryVO.getOuterStatus()));
            }


            //会员状态
            if(NumberUtil.notNullOrZero(queryVO.getStatus())) {
                list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), queryVO.getStatus()));
            }

            //会员角色
            if(NumberUtil.notNullOrZero(queryVO.getRoleId())) {
                list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), queryVO.getRoleId()));
            }

            //会员名称、注册来源
            if(StringUtils.hasLength(queryVO.getName()) || NumberUtil.notNullOrZero(queryVO.getSource())) {
                Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
                if(StringUtils.hasLength(queryVO.getName())) {
                    list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + queryVO.getName().trim() + "%"));
                }

                if(NumberUtil.notNullOrZero(queryVO.getSource())) {
                    list.add(criteriaBuilder.equal(subMemberJoin.get("source").as(Integer.class), queryVO.getSource()));
                }
            }

            //会员等级
            if(NumberUtil.notNullOrZero(queryVO.getLevel())) {
                Join<Object, Object> levelRightJoin = root.join("levelRight", JoinType.LEFT);
                list.add(criteriaBuilder.equal(levelRightJoin.get("level").as(Integer.class), queryVO.getLevel()));
            }

            //会员类型
            if(NumberUtil.notNullOrZero(queryVO.getMemberTypeId())) {
                Join<Object, Object> memberTypeJoin = root.join("subRole", JoinType.LEFT);
                list.add(criteriaBuilder.equal(memberTypeJoin.get("memberType").get("id").as(Long.class), queryVO.getMemberTypeId()));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Pageable page = PageRequest.of(queryVO.getCurrent() - 1, queryVO.getPageSize(), Sort.by("id").descending());
        Page<MemberRelationDO> pageList = relationRepository.findAll(spec, page);

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(relationDO -> {
            MemberMaintenancePageQueryVO memberVO = new MemberMaintenancePageQueryVO();
            memberVO.setMemberId(relationDO.getSubMember().getId());
            memberVO.setValidateId(relationDO.getId());
            memberVO.setName(relationDO.getSubMember().getName());
            memberVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            memberVO.setRoleId(relationDO.getSubRoleId());
            memberVO.setRoleName(relationDO.getSubRoleName());
            memberVO.setSourceName(MemberRegisterSourceEnum.getCodeMessage(relationDO.getSubMember().getSource()));
            memberVO.setRegisterTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));
            memberVO.setLevel(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getLevel());
            memberVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
            memberVO.setStatus(relationDO.getStatus());
            memberVO.setStatusName(MemberStatusEnum.getCodeMessage(relationDO.getStatus()));
            memberVO.setInnerStatus(relationDO.getInnerStatus());
            memberVO.setInnerStatusName(MemberInnerStatusEnum.getCodeMsg(relationDO.getInnerStatus()));
            memberVO.setOuterStatus(relationDO.getOuterStatus());
            memberVO.setOuterStatusName(MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()));

            Boolean enableMultiTenancy = siteService.isEnableMultiTenancy(headers).getData();
            if (relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode()) || relationDO.getOuterStatus().equals(MemberOuterStatusEnum.MODIFY_PASSED.getCode())) {
                if (relationDO.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
                    memberVO.setShowFreeze(true);
                    memberVO.setShowUnfreeze(false);
                    //如果开启saas多租户部署，就隐藏修改按钮
                    memberVO.setShowCorrect(!enableMultiTenancy);
                    memberVO.setShowEliminate(true);
                    memberVO.setShowBlacklist(true);
                } else {
                    memberVO.setShowFreeze(false);
                    memberVO.setShowUnfreeze(relationDO.getStatus().equals(MemberStatusEnum.FROZEN.getCode()));
                    memberVO.setShowCorrect(false);
                    memberVO.setShowEliminate(false);
                    memberVO.setShowBlacklist(false);
                }
            } else {
                memberVO.setShowFreeze(false);
                memberVO.setShowUnfreeze(false);
                memberVO.setShowCorrect(false);
                memberVO.setShowEliminate(false);
                memberVO.setShowBlacklist(false);
            }

            return memberVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 会员处理页面 - 会员详情
     *
     * @param headers HttpHeaders信息
     * @param idVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberMaintenanceDetailVO> getSubMemberDetail(HttpHeaders headers, ValidateIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(idVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        SubMemberDetailVO subMemberDetailVO = baseMemberDetailService.getSubMemberDetail(relationDO);

        MemberMaintenanceDetailVO detailVO = new MemberMaintenanceDetailVO();
        BeanUtils.copyProperties(subMemberDetailVO, detailVO);

        //详细信息分组内容
        detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetailText(relationDO.getSubMember(), MemberDetailVersionEnum.USING));

        //外部历史记录（即历史流转记录）
        detailVO.setOuterHistory(baseMemberHistoryService.listMemberOuterHistory(relationDO));

        return Wrapper.success(detailVO);
    }

    /**
     * 会员冻结、解冻
     *
     * @param headers Http头部信息
     * @param statusVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateMemberRelationFreezeStatus(HttpHeaders headers, MemberFreezeStatusVO statusVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(statusVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        relationDO.setStatus(statusVO.getStatus());
        relationRepository.saveAndFlush(relationDO);

        //内部记录
        MemberValidateHistoryOperationEnum operationEnum = statusVO.getStatus().equals(MemberStatusEnum.NORMAL.getCode()) ? MemberValidateHistoryOperationEnum.UNFREEZE_MEMBER : MemberValidateHistoryOperationEnum.FREEZE_MEMBER;
        baseMemberHistoryService.saveMemberInnerHistory(relationDO, loginUser, operationEnum, statusVO.getReason());

        //外部记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, relationDO.getRole().getRoleName(), operationEnum, MemberStatusEnum.getCodeMessage(relationDO.getStatus()), statusVO.getReason());

        //通知支付服务，冻结-解冻资金账户
        payFeignService.notifyUpdateMemberAssetAccount(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId(), relationDO.getRelType(), relationDO.getStatus());

        return Wrapper.success();
    }

    /**
     * 会员处理 - 会员淘汰（解除关系）
     *
     * @param headers HttpHeaders信息
     * @param vo      接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateMemberEliminatedStatus(HttpHeaders headers, MemberEliminateOrBlacklistVO vo) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(vo.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        relationDO.setStatus(MemberStatusEnum.ELIMINATED.getCode());
        relationRepository.saveAndFlush(relationDO);

        String reason = (StringUtils.hasLength(vo.getDate()) ? vo.getDate() : "").concat(",").concat(vo.getReason());

        //内部记录
        baseMemberHistoryService.saveMemberInnerHistory(relationDO, loginUser, MemberValidateHistoryOperationEnum.ELIMINATE_MEMBER, reason);

        //外部记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, relationDO.getRole().getRoleName(), MemberValidateHistoryOperationEnum.ELIMINATE_MEMBER, MemberStatusEnum.getCodeMessage(relationDO.getStatus()), reason);

        //通知支付服务，冻结资金账户
        payFeignService.notifyToFreezeAssetAccount(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId(), relationDO.getRelType());

        return Wrapper.success();
    }

    /**
     * 会员处理 - 会员黑名单
     *
     * @param headers HttpHeaders信息
     * @param vo      接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateMemberBlacklistStatus(HttpHeaders headers, MemberEliminateOrBlacklistVO vo) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(vo.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        relationDO.setStatus(MemberStatusEnum.BLACK_LIST.getCode());
        relationRepository.saveAndFlush(relationDO);

        String reason = (StringUtils.hasLength(vo.getDate()) ? vo.getDate() : "").concat(",").concat(vo.getReason());

        //内部记录
        baseMemberHistoryService.saveMemberInnerHistory(relationDO, loginUser, MemberValidateHistoryOperationEnum.BLACK_LIST, reason);

        //外部记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, relationDO.getRole().getRoleName(), MemberValidateHistoryOperationEnum.BLACK_LIST, MemberStatusEnum.getCodeMessage(relationDO.getStatus()), reason);

        //通知支付服务，冻结资金账户
        payFeignService.notifyToFreezeAssetAccount(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId(), relationDO.getRelType());

        return Wrapper.success();
    }

    /**
     * 会员详情 - 会员基本信息
     *
     * @param headers HttpHeaders信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberMaintenanceDetailBasicVO> getMemberDetailBasic(HttpHeaders headers, ValidateIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(idVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        Wrapper<WorkflowTaskListBO> result = baseMemberValidateService.getMemberProcessSteps(relationDO);
        if(result.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(result.getCode(), result.getMessage());
        }

        SubMemberDetailVO subMemberDetailVO = baseMemberDetailService.getSubMemberDetail(relationDO);

        MemberMaintenanceDetailBasicVO detailVO = new MemberMaintenanceDetailBasicVO();
        BeanUtils.copyProperties(subMemberDetailVO, detailVO);
        //外部流程
        detailVO.setOuterVerifySteps(baseMemberValidateService.getMemberDepositOuterSteps(relationDO));
        detailVO.setCurrentOuterStep(2);

        //内部流程
        detailVO.setInnerVerifySteps(result.getData().getStepList());
        detailVO.setCurrentInnerStep(result.getData().getCurrentStep());
        detailVO.setInnerVerifyProcessName(result.getData().getProcessName());

        //注册信息分组内容
        detailVO.setGroups(baseMemberRegisterDetailService.switchMemberRegisterDetailText(relationDO.getSubMember()));

        //外部历史记录（即历史流转记录）
        detailVO.setOuterHistory(baseMemberHistoryService.listMemberOuterHistory(relationDO));

        //内部历史记录
        detailVO.setInnerHistory(baseMemberHistoryService.listMemberInnerHistory(relationDO));

        return Wrapper.success(detailVO);
    }

    /**
     * 会员详情 - 查询渠道信息（修改页面）
     *
     * @param headers HttpHeaders信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberMaintenanceChannelVO> getMemberDetailChannel(HttpHeaders headers, ValidateIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(idVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }


        MemberMaintenanceChannelVO channelVO = new MemberMaintenanceChannelVO();
        //渠道信息
        if(relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            channelVO.setUpperRelationId(relationDO.getChannel().getAgentArea().getUpperRelationId());
            List<MemberRelationDO> upperMembers = relationRepository.findBySubMemberIdAndSubRoleIdAndRelType(loginUser.getMemberId(), loginUser.getMemberRoleId(), MemberRelationTypeEnum.OTHER.getCode());
            channelVO.setUpperMembers(CollectionUtils.isEmpty(upperMembers) ? Stream.of(new UpperRelationIdAndNameVO(0L, "")).collect(Collectors.toList()) : upperMembers.stream().map(relation -> new UpperRelationIdAndNameVO(relation.getMemberId(), relation.getMember().getName())).collect(Collectors.toList()));
            channelVO.setChannelLevelTag(relationDO.getChannel().getChannelLevelTag());
            channelVO.setChannelTypeId(relationDO.getChannel().getChannelType().getId());
            channelVO.setAreaCodes(AgentAreaUtil.transferToCodeList(relationDO.getChannel().getAgentArea()));
            channelVO.setChannelTypes(channelTypeRepository.findAll(Sort.by("id").ascending()).stream().map(channelTypeDO -> new ChannelTypeIdAndNameVO(channelTypeDO.getId(), MemberChannelTypeEnum.getMsg(channelTypeDO.getChannelTypeEnum()))).collect(Collectors.toList()));
            channelVO.setRemark(relationDO.getChannel().getRemark());
        }

        return Wrapper.success(channelVO);
    }

    /**
     * 会员详情 - 修改渠道信息 - 查询省列表
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 返回信息
     */
    @Override
    public Wrapper<List<CountryAreaCodeNameVO>> getProvinceList(HttpHeaders headers, UpperRelationIdVO idVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);
        return baseMemberValidateService.getProvinceList(idVO.getUpperRelationId());
    }

    /**
     * 会员详情 - 修改渠道信息 - 查询市列表
     *
     * @param headers Http头部信息
     * @param codeVO  接口参数
     * @return 返回信息
     */
    @Override
    public Wrapper<List<CountryAreaCodeNameVO>> getCityList(HttpHeaders headers, UpperRelationIdAndAreaCodeVO codeVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);
        return baseMemberValidateService.getCityList(codeVO.getUpperRelationId(), codeVO.getProvinceCode());
    }

    /**
     * 会员详情 - 修改渠道信息
     *
     * @param headers  Http头部信息
     * @param updateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateMemberDetailChannel(HttpHeaders headers, MemberMaintenanceChannelUpdateVO updateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(updateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        if(!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_CHANNEL_MEMBER_TYPE);
        }

        return baseMemberValidateService.updateChannelAgentAreas(relationDO,  updateVO.getUpperRelationId(), loginUser.getMemberId(), loginUser.getMemberRoleId(), updateVO.getChannelTypeId(), updateVO.getAreas(), updateVO.getRemark());
    }

    /**
     * 会员详情 - 会员档案信息
     *
     * @param headers HttpHeader信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberMaintenanceRecordVO> getMemberRecords(HttpHeaders headers, ValidateIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(idVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MemberMaintenanceRecordVO recordVO = new MemberMaintenanceRecordVO();
        recordVO.setClassification(baseMemberClassificationService.getMemberClassification(relationDO));
        recordVO.setDepositDetails(baseMemberDepositDetailService.switchMemberDepositoryDetailText(relationDO));
        recordVO.setQualities(baseMemberQualificationService.findMemberQualities(relationDO));
        return Wrapper.success(recordVO);
    }

    /**
     * 会员详情 - 会员档案 - 查询入库分类信息（修改页面）
     *
     * @param headers HttpHeader信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberClassifyQueryVO> getMemberClassification(HttpHeaders headers, ValidateIdVO idVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(idVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return Wrapper.success(baseMemberClassificationService.findMemberClassification(relationDO));
    }

    /**
     * “修改入库分类信息” - “适用区域”-省列表
     *
     * @param headers Http头部信息
     * @return 查询结果
     */
    @Override
    public Wrapper<List<CountryAreaCodeNameVO>> getClassifyProvinces(HttpHeaders headers) {
        return baseCountryAreaService.listAllProvince();
    }

    /**
     * “修改入库分类” - “适用区域”-根据省编码查询市列表
     *
     * @param headers Http头部信息
     * @param codeVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<CountryAreaCodeNameVO>> getClassifyCities(HttpHeaders headers, ProvinceCodeVO codeVO) {
        return baseCountryAreaService.listAllCitiesByProvinceCode(codeVO.getProvinceCode());
    }

    /**
     * “修改入库分类” - 品类信息 - 查询结算方式与发票类型
     *
     * @param headers Http头部信息
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberClassifyCategoryItemVO> getToClassifyCategoryItems(HttpHeaders headers) {
        MemberClassifyCategoryItemVO itemVO = new MemberClassifyCategoryItemVO();
        itemVO.setPayTypes(baseMemberRuleRepository.findByRuleTypeAndStatus(PlatformRuleTypeEnum.PURCHASE_CONTRACT.getCode(), EnableDisableStatus.ENABLE.getCode()).stream().map(baseMemberRule -> new BusinessCategoryPayTypeVO(baseMemberRule.getMethodCode(), PurchaseContractPayTypeEnum.getNameByCode(baseMemberRule.getMethodCode()))).sorted(Comparator.comparingInt(BusinessCategoryPayTypeVO::getPayType)).collect(Collectors.toList()));
        itemVO.setInvoiceTypes(Arrays.stream(BusinessCategoryInvoiceTypeEnum.values()).map(e -> new BusinessCategoryInvoiceTypeVO(e.getCode(), e.getName())).sorted(Comparator.comparingInt(BusinessCategoryInvoiceTypeVO::getInvoiceType)).collect(Collectors.toList()));
        itemVO.setCurrencyTypes(Arrays.stream(CurrencyTypeEnum.values()).map(e -> new BusinessCurrencyTypeVO(e.getCode(), e.getMsg())).sorted(Comparator.comparingInt(BusinessCurrencyTypeVO::getCurrencyType)).collect(Collectors.toList()));
        itemVO.setSettlementDocuments(Arrays.stream(SettlementDocumentsEnum.values()).map(e -> new BusinessSettlementDocumentsTypeVO(e.getCode(), e.getMsg())).sorted(Comparator.comparingInt(BusinessSettlementDocumentsTypeVO::getSettlementDocumentsType)).collect(Collectors.toList()));
        itemVO.setPaymentTypes(Arrays.stream(PaymentTypeEnum.values()).map(e -> new BusinessPaymentTypeVO(e.getCode(), e.getMsg())).sorted(Comparator.comparingInt(BusinessPaymentTypeVO::getPaymentType)).collect(Collectors.toList()));
        itemVO.setAdvanceCharges(Arrays.stream(AdvanceChargeEnum.values()).map(e -> new BusinessAdvanceChargeTypeVO(e.getCode(), e.getMsg())).sorted(Comparator.comparingInt(BusinessAdvanceChargeTypeVO::getAdvanceChargeType)).collect(Collectors.toList()));
        return Wrapper.success(itemVO);
    }

    /**
     * 会员详情 - 会员档案 - 修改入库分类信息
     *
     * @param headers  HttpHeader信息
     * @param updateVO 接口参数
     * @return 查询结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateMemberClassification(HttpHeaders headers, MemberMaintenanceClassificationUpdateVO updateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(updateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //检查并保存入库分类信息
        Wrapper<Void> result = baseMemberClassificationService.saveMemberClassification(relationDO, updateVO.getRemark(), updateVO.getCurrencyType(), updateVO.getCode(), updateVO.getPartnerType(), updateVO.getMaxAmount(), updateVO.getAreaCodes(), updateVO.getCategories());
        if(result.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(result.getCode(), result.getMessage());
        }

        relationRepository.saveAndFlush(relationDO);
        return Wrapper.success();
    }

    /**
     * 会员详情 - 会员档案 - 分页查询考察信息
     *
     * @param headers HttpHeader信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberRecordInspectPageQueryVO>> pageMemberInspect(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }
        return memberInspectService.pageMemberInspect(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMember(), relationDO.getSubRoleId(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情- 会员档案 - 分页查询考评信息
     *
     * @param headers HttpHeader信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberAppraisalPageQueryVO>> pageMemberAppraisal(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }
        return memberAppraisalService.pageMemberAppraisal(relationDO.getMember(), relationDO.getRole(), relationDO.getSubMember(), relationDO.getSubRole(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员档案 - 分页查询会员整改
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberRecordRectifyVO>> pageMemberRecordRectify(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }
        return memberRectifyService.pageMemberRecordRectify(relationDO.getMember(), relationDO.getRole(), relationDO.getSubMember(), relationDO.getSubRole(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员等级信息
     *
     * @param headers Http头部信息
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberValidateDetailLevelVO> getMemberLevelDetail(HttpHeaders headers, MemberValidateVO validateVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailLevel(relationDO);
    }

    /**
     * 会员详情 - 会员等级信息 - 分页查询交易分获取记录
     *
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberDetailLevelHistoryVO>> pageMemberLevelDetailHistory(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberLevelDetailHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize(), ServiceConfig.DEFAULT_DATETIME_FORMATTER);
    }

    /**
     * 会员详情 - 会员权益信息
     *
     * @param headers Http头部信息
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberDetailRightVO> getMemberDetailRight(HttpHeaders headers, MemberValidateVO validateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailRight(relationDO);
    }

    /**
     * 会员详情 - 会员权益信息 - 分页查询会员权益获取记录
     *
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberDetailRightHistoryVO>> pageMemberDetailRightHistory(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailRightHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize(), ServiceConfig.DEFAULT_DATETIME_FORMATTER);
    }

    /**
     * 会员详情 - 会员权益信息 - 分页查询会员权益使用记录
     *
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return  操作结果
     */
    @Override
    public Wrapper<PageData<MemberDetailRightSpendHistoryVO>> pageMemberDetailRightSpendHistory(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailRightSpendHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize(), ServiceConfig.DEFAULT_DATETIME_FORMATTER);
    }

    /**
     * 会员详情 - 会员信用信息
     *
     * @param headers Http头部信息
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberDetailCreditVO> getMemberDetailCredit(HttpHeaders headers, MemberValidateVO validateVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailCredit(relationDO);
    }

    /**
     * 会员详情 - 会员信用信息 - 交易评价汇总
     *
     * @param headers Http头部新
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberDetailCreditCommentSummaryVO> getMemberDetailCreditTradeCommentSummary(HttpHeaders headers, MemberValidateVO validateVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailCreditTradeCommentSummary(relationDO);
    }

    /**
     * 会员详情 - 会员信用 - 分页查询交易评论历史记录
     *
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberDetailCreditTradeHistoryVO>> pageMemberDetailCreditTradeCommentHistory(HttpHeaders headers, MemberDetailCreditHistoryPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailCreditTradeCommentHistory(relationDO, pageVO.getStarLevel(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员信用信息 - 售后评价汇总
     *
     * @param headers Http头部新
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberDetailCreditCommentSummaryVO> getMemberDetailCreditAfterSaleCommentSummary(HttpHeaders headers, MemberValidateVO validateVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailCreditAfterSaleCommentSummary(relationDO);
    }

    /**
     * 会员详情 - 会员信用 - 分页查询售后评论历史记录
     *
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberDetailCreditAfterSaleHistoryVO>> pageMemberDetailCreditAfterSaleCommentHistory(HttpHeaders headers, MemberDetailCreditHistoryPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailCreditAfterSaleCommentHistory(relationDO, pageVO.getStarLevel(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员信用 - 投诉汇总
     *
     * @param headers Http头部信息
     * @param validateVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberDetailCreditComplainSummaryVO> getMemberDetailCreditComplainSummary(HttpHeaders headers, MemberValidateVO validateVO) {
        memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return memberComplaintService.summaryUpperMemberComplaints(relationDO.getMember(), relationDO.getRoleId(), relationDO.getSubMember(), relationDO.getSubRoleId());
    }

    /**
     * 会员详情 - 会员信用 - 分页查询投诉历史记录
     *
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberCreditComplaintPageQueryVO>> pageMemberDetailCreditComplainHistory(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }
        return memberComplaintService.pageUpperMemberComplaint(relationDO.getMember(), relationDO.getRoleId(), relationDO.getSubMember(), relationDO.getSubRoleId(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员变更 - 分页查询会员变更记录
     *
     * @param headers HttpHeaders信息
     * @param pageVO  接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberDepositDetailHistoryVO>> pageMemberDepositDetailHistory(HttpHeaders headers, ValidateIdPageVO pageVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return Wrapper.success(baseMemberHistoryService.pageMemberDepositDetailHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize()));
    }

    @Override
    public Wrapper<PageData<PlatformPageQueryMemberVO>> pagePlatformMembers(HttpHeaders headers, PlatformMemberQueryVO queryVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        //当前会员的下级会员id和下级角色id进行一对一绑定
        List<MemberRelationDO> subMemberIdAndSubRoleIds = relationRepository.findAllByMemberIdAndRoleIdAndRelType(loginUser.getMemberId(), loginUser.getMemberRoleId(), MemberRelationTypeEnum.OTHER.getCode()).stream().collect(Collectors.toList());
        //筛选出平台后台的下级会员已经添加为当前会员的下级会员
        List<Long> memberRelationIds = subMemberIdAndSubRoleIds.stream().map(subMemberIdAndSubRoleId -> {
            return relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(subMemberIdAndSubRoleId.getSubMemberId(), subMemberIdAndSubRoleId.getSubRoleId(), MemberRelationTypeEnum.PLATFORM.getCode()).getId();
        }).collect(Collectors.toList());
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            //上级为平台
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));
            //只查询会员类型为“企业会员”和“个人会员,且还没添加为当前用户的下级会员的会员
            list.add(criteriaBuilder.in(root.get("subMemberTypeEnum")).value(Arrays.asList(MemberTypeEnum.MERCHANT.getCode(), MemberTypeEnum.MERCHANT_PERSONAL.getCode())));
            if(CollectionUtil.isNotEmpty(memberRelationIds)){
                list.add(criteriaBuilder.not(criteriaBuilder.in(root.get("id")).value(memberRelationIds)));
            }
            //不显示平台后台的下级会员是当前登录会员，不管什么角色
            list.add(criteriaBuilder.notEqual(root.get("subMemberId").as(Long.class), loginUser.getMemberId()));
            //查询内外部状态都为平台审核通过的
            list.add(criteriaBuilder.equal(root.get("innerStatus").as(Integer.class), PlatformInnerStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode()));

            //会员角色
            if(NumberUtil.notNullOrZero(queryVO.getRoleId())) {
                list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), queryVO.getRoleId()));
            }

            //内部状态
            if(NumberUtil.notNullOrZero(queryVO.getInnerStatus())) {
                list.add(criteriaBuilder.equal(root.get("innerStatus").as(Integer.class), queryVO.getInnerStatus()));
            }

            //外部状态
            if(NumberUtil.notNullOrZero(queryVO.getOuterStatus())) {
                list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), queryVO.getOuterStatus()));
            }

            //会员状态
            if(NumberUtil.notNullOrZero(queryVO.getStatus())) {
                list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), queryVO.getStatus()));
            }

            //注册起始时间
            if(StringUtils.hasLength(queryVO.getStartDate())) {
                LocalDateTime startDate = LocalDateTime.parse(queryVO.getStartDate().concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), startDate));
            }

            //注册结束时间
            if(StringUtils.hasLength(queryVO.getEndDate())) {
                LocalDateTime endDate = LocalDateTime.parse(queryVO.getEndDate().concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), endDate));
            }

            //会员名称
            Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
            if(StringUtils.hasLength(queryVO.getName())) {
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + queryVO.getName().trim() + "%"));
            }

            //注册来源
            if(NumberUtil.notNullOrZero(queryVO.getSource())) {
                list.add(criteriaBuilder.equal(subMemberJoin.get("source").as(Integer.class), queryVO.getSource()));
            }

            //会员等级
            if(NumberUtil.notNullOrZero(queryVO.getLevel())) {
                Join<Object, Object> levelRightJoin = root.join("levelRight", JoinType.LEFT);
                list.add(criteriaBuilder.equal(levelRightJoin.get("level").as(Integer.class), queryVO.getLevel()));
            }

            //会员类型
            if(NumberUtil.notNullOrZero(queryVO.getMemberTypeId())) {
                Join<Object, Object> memberTypeJoin2 = root.join("subRole", JoinType.LEFT);
                list.add(criteriaBuilder.equal(memberTypeJoin2.get("memberType").get("id").as(Long.class), queryVO.getMemberTypeId()));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Pageable page = PageRequest.of(queryVO.getCurrent() - 1, queryVO.getPageSize(), Sort.by("id").descending());
        Page<MemberRelationDO> pageList = relationRepository.findAll(specification, page);

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(relationDO -> {
            PlatformPageQueryMemberVO memberVO = new PlatformPageQueryMemberVO();
            memberVO.setMemberId(relationDO.getSubMemberId());
            memberVO.setUpperMemberId(relationDO.getMemberId());
            memberVO.setValidateId(relationDO.getId());
            memberVO.setRoleId(relationDO.getSubRoleId());
            memberVO.setUpperRoleId(relationDO.getRoleId());
            memberVO.setName(relationDO.getSubMember().getName());
            memberVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            memberVO.setMemberTypeId(relationDO.getSubRole().getMemberType().getTypeEnum());
            memberVO.setCountryCodeId(Optional.ofNullable(countryCodeRepository.findFirstByCode(relationDO.getSubMember().getCountryCode())).map(CountryCodeDO::getId).orElse(null));
            memberVO.setPhone(relationDO.getSubMember().getPhone());
            memberVO.setEmail(relationDO.getSubMember().getEmail());
            memberVO.setUpperRelationId(Optional.ofNullable(relationDO.getChannel()).map(MemberChannelDO::getAgentArea).map(AgentAreaBO::getUpperRelationId).orElse(0L));
            memberVO.setDetail(convertRegisterDetails(relationDO.getSubMember().getRegisterDetails()));
            memberVO.setRelType(relationDO.getRelType());
            memberVO.setRoleName(relationDO.getSubRole().getRoleName());
            memberVO.setSource(relationDO.getSubMember().getSource());
            memberVO.setSourceName(MemberRegisterSourceEnum.getCodeMessage(relationDO.getSubMember().getSource()));
            memberVO.setRegisterTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));

            //从关联的角色查找等级
            memberVO.setLevel(relationDO.getLevelRight().getLevel());
            memberVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            memberVO.setStatus(relationDO.getStatus());
            memberVO.setStatusName(MemberStatusEnum.getCodeMessage(relationDO.getStatus()));
            memberVO.setInnerStatus(relationDO.getInnerStatus());
            memberVO.setInnerStatusName(PlatformInnerStatusEnum.getCodeMsg(relationDO.getInnerStatus()));
            memberVO.setOuterStatus(relationDO.getOuterStatus());
            memberVO.setOuterStatusName(MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()));
            return memberVO;
        }).collect(Collectors.toList())));
    }

    //转换会员的注册信息
    private Map<String, Object> convertRegisterDetails(Set<MemberRegisterDetailDO> registerDetails) {
        return registerDetails.stream().collect(Collectors.toMap(MemberRegisterDetailDO::getFieldName, registerDetail -> {
            if ("select".equals(registerDetail.getFieldType()) || "radio".equals(registerDetail.getFieldType())) {
                return registerDetail.getLabels().stream().findFirst().map(MemberDetailLabelBO::getLabelId).orElse(null);
            }
            else if("checkbox".equals(registerDetail.getFieldType())){
                return registerDetail.getLabels().stream().map(MemberDetailLabelBO::getLabelId).collect(Collectors.toList());
            }
            else if("area".equals(registerDetail.getFieldType())){
                Map areaMap = new HashMap();
                areaMap.put("cityCode", registerDetail.getCityCode());
                areaMap.put("districtCode", registerDetail.getDistrictCode());
                areaMap.put("provinceCode", registerDetail.getProvinceCode());
                return areaMap;
            }
            return registerDetail.getDetail();
        }));

    }

    /**
     * 根据会员id和角色id，查询会员角色为服务提供者的下级会员列表
     *
     * @param headers HttpHeaders信息
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberManageQueryVO>> subOrdinateMemberList(HttpHeaders headers, MemberNameVO nameVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromBusinessPlatform(headers);
        Specification<MemberRelationDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), loginUser.getMemberRoleId()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), MemberStatusEnum.NORMAL.getCode()));
            if (StringUtils.hasLength(nameVO.getMemberName())) {
                list.add(criteriaBuilder.like(root.get("subRoleName").as(String.class), "%" + nameVO.getMemberName() + "%"));
            }
            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };
        Pageable page = PageRequest.of(nameVO.getCurrent() - 1, nameVO.getPageSize(), Sort.by("id").ascending());
        Page<MemberRelationDO> relationDOList = relationRepository.findAll(specification, page);
        return Wrapper.success(new PageData<>(relationDOList.getTotalElements(),relationDOList.getContent().stream().map(p -> {
            MemberManageQueryVO queryVO = new MemberManageQueryVO();
            queryVO.setId(p.getId());
            queryVO.setMemberId(p.getSubMemberId());
            queryVO.setName(p.getSubMember().getName());
            queryVO.setRoleId(p.getSubRoleId());
            queryVO.setRoleName(p.getSubRole().getRoleName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(p.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setLevel(p.getLevelRight().getLevel());
            queryVO.setLevelTag(p.getLevelRight().getLevelTag());
            return queryVO;
        }).collect(Collectors.toList())));
    }
}
